#!/bin/bash

version=1.4

TARGET_DIRECTORY="."              # files are extracted to this directory

RENAME_EXTRACTED_FILES=false      # rename extracted file to the name of the directory in which it's located plus .avi

FIRST_RAR_FILE_SUFFIX="rar"     #  E.g. "rar" or "part01.rar" (only the first rar-files can have this suffix)

VIDEO_FILE_SUFFIX="auto"          # E.g. "avi" or "mkv" ("auto" tries to detect the suffix automatically)



if $RENAME_EXTRACTED_FILES
then
    rename="on"
else
    rename="off"
fi

if [ "$TARGET_DIRECTORY" = "." ]
then
    target_directory_echo='current directory'
else
    target_directory_echo="$TARGET_DIRECTORY"
fi

if [ $# = 0 ]
then
    echo -e "\n multi-xtract.sh $version extracts episodes from rar-archives to a specified directory."
    echo -e "\n Usage\n   multi-xtract.sh [options] <directories>     (directories must be separated by white space)"
    echo -e "\n Options"
    echo -e "   -r                      renames the extracted .avi using its parent directory name. Default: $rename"
    echo -e "   -d <target_directory>   <target_directory> is a relative or absolute path. Default: $target_directory_echo"
    echo -e "   -s <first_rar_suffix>   suffix of the first rar file. Default: $FIRST_RAR_FILE_SUFFIX"
    echo -e "   -v <video_file_suffix>  suffix of the video file. Default: $VIDEO_FILE_SUFFIX\n"
    echo -e " Usage examples"
    echo -e "   multi-xtract.sh .                                       (extract the episode in the current directory)"
    echo -e "   multi-xtract.sh *                                       (extract the episodes in all sub-directories)"
    echo -e "   multi-xtract.sh Yet.Another.Series.S01E01.*             (extract Episode 1)"
    echo -e "   multi-xtract.sh Yet.Another.Series.S01E0[1-9]*          (extract Episode 1 to 9)"
    echo -e "   multi-xtract.sh Yet.Another.Series.S01E0[1,2,4]*        (extract Episode 1, 2 and 4)"
    echo -e "   multi-xtract.sh Yet.Another.Series.S01E{01,02,15}*      (extract Episode 1, 2 and 15)\n"
    exit
fi

if ! type unrar > /dev/null 2>&1
then
    echo -e "\n Error: Your need 'unrar' to use this script.\n"
    exit 1
fi

shift_count=0

while getopts ":v:d:s:r" option
do
  case $option in
    d)   
      TARGET_DIRECTORY="$OPTARG"
      let shift_count+=2
      ;;
    r)
      RENAME_EXTRACTED_FILES=true
      let shift_count++
      ;;
    s)   
      FIRST_RAR_FILE_SUFFIX="$OPTARG"
      let shift_count+=2
      ;;      
    v)
      VIDEO_FILE_SUFFIX="$OPTARG"
      let shift_count+=2      
     ;;
   \?)
      echo -e "\n Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo -e "\n Option -$OPTARG requires an argument.\n" >&2
      exit 1
      ;;
  esac
done

shift $shift_count

if [ -z "$*" ]
then
    echo -e "\n Error: Please specify one or more episode directory paths. \n"
    exit 1
fi

if [ ! -d "$TARGET_DIRECTORY" -o ! -w "$TARGET_DIRECTORY" ]
then
    echo -e "\n Error: The directory $TARGET_DIRECTORY does not exist or is not writable.\n"
    exit 1
fi

echo -e "\n The extracted files will be $(if $RENAME_EXTRACTED_FILES; then echo "renamed and "; fi)moved to $(cd "$TARGET_DIRECTORY"; pwd)"

error_count=0
extract_count=0
script_execution_directory="$PWD"

for episode_directory_path in "$@"
do
  if [ "${episode_directory_path:0:1}" = / ]
  then
      absolute_episode_directory_path="$episode_directory_path"
  else
      absolute_episode_directory_path="$script_execution_directory/$episode_directory_path"
  fi

   if [ -d "$absolute_episode_directory_path" ]
   then
       cd "$absolute_episode_directory_path"

       if [ $(ls -l *.$FIRST_RAR_FILE_SUFFIX 2> /dev/null | wc -l) -eq 0 ]  # if there is no file with this suffix..
       then
           let error_count++
           echo -e "\n Error: Please change the first rar file suffix which is currently \"$FIRST_RAR_FILE_SUFFIX\""
           echo -e "\n There is no file with this suffix in $PWD."
       elif [ $(ls -l *.$FIRST_RAR_FILE_SUFFIX | wc -l ) -gt 1 ]  # if there is more than one file with this suffix..
       then 
           let error_count++
           echo -e "\n Error: Please change the first rar file suffix which is currently set to \"$FIRST_RAR_FILE_SUFFIX\""
           echo -e "\n There is more than one file with this suffix in $PWD. "
       else
           rar_file_name=$(ls *.$FIRST_RAR_FILE_SUFFIX 2> /dev/null)

           if [ $episode_directory_path = . ]
           then 
               episode_directory_path="$PWD"  # for echo output only
           else    
               episode_directory_path="${episode_directory_path%/}"               
           fi

           echo -en "\n Extracting episode ${episode_directory_path##*/} ...   "

           if unrar e "${rar_file_name}" > /dev/null
           then
               echo -e "OK"
               let extract_count++
               if [ $VIDEO_FILE_SUFFIX != "auto" ]
               then
                 video_file_name=$(unrar l "$rar_file_name" | egrep -o "[[:alpha:]]{3,}-[[:print:]]*.$VIDEO_FILE_SUFFIX")
               else 
                 video_file_name=$(unrar l "$rar_file_name" | egrep -v "[[:print:]]+\.rar" | egrep -o "[[:alpha:]]+-[[:print:]]+\.[[:alpha:]]{3}")
                 VIDEO_FILE_SUFFIX=$(echo $video_file_name | egrep -o "\.[[:alpha:]]{3}")
                 VIDEO_FILE_SUFFIX="${VIDEO_FILE_SUFFIX:1}"  # remove the dot
               fi
               video_file_path="$PWD/$video_file_name"
               file "$video_file_name" > /dev/null 2>&1
               video_file_exists=$?

               if [ $video_file_exists -eq 0 ]
               then
                   cd "$script_execution_directory"    # the directory from which the script was started
                   mv -f "$video_file_path" "$TARGET_DIRECTORY" 2> /dev/null
                   if $RENAME_EXTRACTED_FILES
                   then
                       cd "$absolute_episode_directory_path"   
                       new_video_file_name="${PWD##*/}.$VIDEO_FILE_SUFFIX";  # get the name of the episode directory
                       cd "$script_execution_directory"
                       cd "$TARGET_DIRECTORY" 
                       mv "$video_file_name" "$new_video_file_name"
                   fi
               else
                   let error_count++                  
                   echo -e "\n Error: Cannot find the extracted file '${video_file_name}'."
               fi               
           else
               echo
               let error_count++
           fi
       fi
   else
       let error_count++
       echo -e "\n Error: Directory '$episode_directory_path' does not exist."                   
   fi                              
done

if [ $error_count -gt 0 ]
then
    echo -e "\n Note: $error_count error$(if [ $error_count -ne 1 ]; then echo "s"; fi) occured!"
fi

echo -e "\n Extracted $extract_count file$(if [ $extract_count -ne 1 ]; then echo "s"; fi).\n"

exit $error_count
